﻿using Renci.iRods.Common;

namespace Renci.iRods.Packets
{
    [PacketAttribute("MsgHeader_PI")]
    internal class MessageHeaderPacket : Packet
    {
        //internal const string NAME = "MsgHeader_PI";

        [PacketField("type", 0, DataTypes.Enum, 32)]
        public MessageTypes MessageType { get; private set; }

        /// <summary>
        /// Gets or sets the length of the main message.
        /// </summary>
        /// <value>
        /// The length of the message.
        /// </value>
        [PacketField("msgLen", 1, DataTypes.Int)]
        public int MessageLength { get; private set; }

        /// <summary>
        /// Gets or sets the length of the error struct.
        /// </summary>
        /// <value>
        /// The length of the error.
        /// </value>
        [PacketField("errorLen", 2, DataTypes.Int)]
        public int ErrorLength { get; private set; }

        /// <summary>
        /// Gets or sets the length of the optional byte stream.
        /// </summary>
        /// <value>
        /// The length of the binary string.
        /// </value>
        [PacketField("bsLen", 3, DataTypes.Int)]
        public int BinaryStringLength { get; private set; }

        /// <summary>
        /// Gets or sets an additional integer info, for API, it is the apiReqNum.
        /// </summary>
        /// <value>
        /// The int info.
        /// </value>
        [PacketField("intInfo", 4, DataTypes.Int)]
        public int InformationNumber { get; private set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="MessageHeaderPacket"/> class.
        /// </summary>
        public MessageHeaderPacket()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="MessageHeaderPacket"/> class.
        /// </summary>
        /// <param name="messageType">Type of the message.</param>
        /// <param name="messageLength">Length of the message.</param>
        /// <param name="errorLength">Length of the error.</param>
        /// <param name="binaryLength">Length of the binary.</param>
        /// <param name="apiRequestNumber">The API request number.</param>
        public MessageHeaderPacket(MessageTypes messageType, int messageLength, int errorLength, int binaryLength, int apiRequestNumber)
        {
            this.MessageType = messageType;
            this.MessageLength = messageLength;
            this.ErrorLength = errorLength;
            this.BinaryStringLength = binaryLength;
            this.InformationNumber = apiRequestNumber;
        }

        ///// <summary>
        ///// Packs packet as binary array.
        ///// </summary>
        ///// <returns></returns>
        //public override byte[] PackAsBinary()
        //{
        //    throw new NotImplementedException();
        //}

        ///// <summary>
        ///// Packs packet as XML array.
        ///// </summary>
        ///// <returns></returns>
        //public override byte[] PackAsXml()
        //{
        //    StringBuilder xml = new StringBuilder();
        //    xml.AppendFormat("<{0}>", MessageHeaderPacket.NAME);
        //    switch (this.MessageType)
        //    {
        //        case MessageTypes.Version:
        //            xml.Append("<type>RODS_VERSION</type>");
        //            break;
        //        case MessageTypes.Connect:
        //            xml.Append("<type>RODS_CONNECT</type>");
        //            break;
        //        case MessageTypes.Disconnect:
        //            xml.Append("<type>RODS_VERSION</type>");
        //            break;
        //        case MessageTypes.Reconnect:
        //            xml.Append("<type>RODS_RECONNECT</type>");
        //            break;
        //        case MessageTypes.Authenticate:
        //            xml.Append("<type>RODS_REAUTH</type>");
        //            break;
        //        case MessageTypes.Request:
        //            xml.Append("<type>RODS_API_REQ</type>");
        //            break;
        //        case MessageTypes.Reply:
        //            xml.Append("<type>RODS_API_REPLY</type>");
        //            break;
        //        default:
        //            break;
        //    }

        //    xml.AppendFormat("<msgLen>{0}</msgLen>", this.MessageLength);
        //    xml.AppendFormat("<errorLen>{0}</errorLen>", this.ErrorLength);
        //    xml.AppendFormat("<bsLen>{0}</bsLen>", this.BinaryStringLength);
        //    xml.AppendFormat("<intInfo>{0}</intInfo>", this.ApiRequestNumber);
        //    xml.AppendFormat("</{0}>", MessageHeaderPacket.NAME);

        //    return Encoding.ASCII.GetBytes(xml.ToString());
        //}

        ///// <summary>
        ///// Unpacks packet from binary array.
        ///// </summary>
        ///// <param name="data">The data.</param>
        //public override void Unpack(byte[] data)
        //{
        //    throw new NotImplementedException();
        //}

        ///// <summary>
        ///// Unpacks packet from XML string.
        ///// </summary>
        ///// <param name="xml">The XML.</param>
        //public override void Unpack(XElement xml)
        //{
        //    if (!xml.Name.LocalName.Equals(MessageHeaderPacket.NAME))
        //        throw new InvalidOperationException(string.Format("'{0}' is expected", MessageHeaderPacket.NAME));

        //    switch (xml.Element("type").Value)
        //    {
        //        case "RODS_VERSION":
        //            this.MessageType = MessageTypes.Version;
        //            break;
        //        case "RODS_CONNECT":
        //            this.MessageType = MessageTypes.Connect;
        //            break;
        //        case "RODS_DISCONNECT":
        //            this.MessageType = MessageTypes.Disconnect;
        //            break;
        //        case "RODS_RECONNECT":
        //            this.MessageType = MessageTypes.Reconnect;
        //            break;
        //        case "RODS_REAUTH":
        //            this.MessageType = MessageTypes.Authenticate;
        //            break;
        //        case "RODS_API_REQ":
        //            this.MessageType = MessageTypes.Request;
        //            break;
        //        case "RODS_API_REPLY":
        //            this.MessageType = MessageTypes.Reply;
        //            break;
        //        default:
        //            break;
        //    }

        //    this.MessageLength = int.Parse(xml.Element("msgLen").Value);
        //    this.ErrorLength = int.Parse(xml.Element("errorLen").Value);
        //    this.BinaryStringLength = int.Parse(xml.Element("bsLen").Value);
        //    this.ApiRequestNumber = int.Parse(xml.Element("intInfo").Value);
        //}

    }
}
